package algorithms.queue;

/**
 * 循环队列
 */
public class LoopQueue {
    // 头指针
    private int front;
    // 尾指针
    private int tail;
    // 容量
    private int capacity;
    // 存放数据
    private Object[] data;

    public LoopQueue() {
        new LoopQueue(16);
    }


    public LoopQueue(int capacity) {
        // capacity + 1 是因为下标从0开始的,类似与length与size的区别
        this.capacity = capacity <= 0 ? 16 : capacity + 1;
        this.data = new Object[this.capacity];
        this.front = this.tail = 0;
    }

    /**
     * 队列是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        // 相等表面队列已空
        return tail == front;
    }

    /**
     * 队列是否已满
     *
     * @return
     */
    public boolean isFull() {
        // 尾部的下一个元素是头部，就表面队列已经满
        return (tail + 1) % capacity == front;
    }

    public boolean put(Object obj) {
        if (isFull()) {
            return false;
        }
        data[tail] = obj;
        tail = (tail + 1) % capacity;
        return true;
    }

    public Object pop() {
        if (isEmpty()) {
            return null;
        }
        Object res = data[front];
        front = (front + 1) % capacity;
        return res;
    }

    public int length() {
        return (tail + capacity - front) % capacity;
    }

    @Override
    public String toString() {
        StringBuffer toStr = new StringBuffer("[");
        int end = front + length();
        for (int i = front; i < end; i++) {
            toStr.append(data[i % capacity]);
            if (i != end -1) {
                toStr.append(",");
            }
        }
        toStr.append("]");
        return toStr.toString();

    }

}
